﻿using System;
using System.Linq;
using Contrib.Voting.Models;
using Contrib.Voting.Services;
using NineSeas.Extensions;
using NineSeas.Models;
using Orchard;
using Orchard.ContentManagement;
using Orchard.Data;
namespace NineSeas.Services
{
    public class SocialStatisticService: ISocialStatisticService
    {
        private readonly IOrchardServices _orchardServices;
        private readonly IVotingService _votingService;
        private readonly IRepository<ResultRecord> _resultRepository;
        public SocialStatisticService(IOrchardServices orchardServices,
            IVotingService votingService,
            IRepository<ResultRecord> resultRepository)
        {
            this._orchardServices = orchardServices;
            this._votingService = votingService;
            this._resultRepository = resultRepository;
        }
        public void UpdateViews<T>(T part) where T : ContentPart, IViewCountable
        {
            var userName = GetCurrentUsername();

            var currentVote = _votingService.Get(vote =>
                vote.ContentItemRecord == part.ContentItem.Record &&
                vote.Username == userName &&
                vote.Dimension == part.Dimension).FirstOrDefault();

            if (currentVote == null)
            {
                _votingService.Vote(part.ContentItem, userName, _orchardServices.WorkContext.HttpContext.Request.UserHostAddress, 1, part.Dimension);

                part.TotalViews = GetTotal(part, part.Dimension, Constants.VotingFunctions.Count);
            }
        }

        public void UpdateLikes<T>(T part, bool like) where T : ContentPart, ILikeable
        {
            var userName = GetCurrentUsername();
            var currentVote = _votingService.Get(vote =>
                vote.ContentItemRecord == part.ContentItem.Record &&
                vote.Username == userName &&
                vote.Hostname == _orchardServices.WorkContext.HttpContext.Request.UserHostAddress &&
                vote.Dimension == part.Dimension).FirstOrDefault();

            if (currentVote == null)
            {
                _votingService.Vote(part.ContentItem, userName, _orchardServices.WorkContext.HttpContext.Request.UserHostAddress, like ? 1 : 0, part.Dimension);
            }
            else
            {
                _votingService.ChangeVote(currentVote, like ? 1 : 0);
            }

            part.TotalLikes = GetTotal(part, part.Dimension, Constants.VotingFunctions.Sum);
        }

        public bool IsLiked<T>(T part) where T : ContentPart, ILikeable
        {
            if (part == default(T)) return false;

            var userName = GetCurrentUsername();
            var currentVote = _votingService.Get(vote =>
                vote.ContentItemRecord == part.ContentItem.Record &&
                vote.Username == userName &&
                vote.Hostname == _orchardServices.WorkContext.HttpContext.Request.UserHostAddress &&
                vote.Dimension == part.Dimension).FirstOrDefault();

            return currentVote != null && currentVote.Value == 1;
        }

        private int GetTotal<T>(T part, string dimension, string function) where T : ContentPart
        {
            var result = _resultRepository.Fetch(r => r.ContentItemRecord.Id == part.Id
                            && r.Dimension == dimension
                            && r.FunctionName == function,
                    x => x.Asc(r => r.Value), 0, 1).FirstOrDefault();

            return result != null ? Convert.ToInt32(result.Value) : 0;
        }
        private string GetCurrentUsername()
        {
            var currentUser = _orchardServices.WorkContext.CurrentUser;
            var userName = String.Empty;
            if (currentUser != null)
            {
                userName = currentUser.UserName;
            }
            else
            {
                userName = _orchardServices.WorkContext.HttpContext.Request.UserHostAddress;
                if (!string.IsNullOrWhiteSpace(_orchardServices.WorkContext.HttpContext.Request.Headers["X-Forwarded-For"]))
                    userName += "-" + _orchardServices.WorkContext.HttpContext.Request.Headers["X-Forwarded-For"];

            }
            return userName;
        }
    }
}